package com.base.base

import android.annotation.SuppressLint
import android.app.Activity
import android.app.ActivityManager
import android.content.Context
import android.content.Intent
import android.graphics.*
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.os.Build
import android.renderscript.Allocation
import android.renderscript.Element
import android.renderscript.RenderScript
import android.renderscript.ScriptIntrinsicBlur
import android.util.Log
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.PopupWindow
import android.widget.Toast
import androidx.annotation.FloatRange
import androidx.annotation.IntRange
import androidx.annotation.StringRes
import androidx.core.graphics.toColorInt
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.RecyclerView
import java.io.ByteArrayOutputStream
import java.text.SimpleDateFormat
import java.util.*
import kotlin.math.*

object Instance{
    var toast: Toast? = null
}

//------------------------------------------------Toast提示-----------------------------------------------------------

fun Context.toast(charSequence: CharSequence?){
    charSequence ?: return
    Instance.toast = Instance.toast ?: Toast.makeText(applicationContext,charSequence,Toast.LENGTH_SHORT)
    Instance.toast?.setText(charSequence)
    Instance.toast?.show()
}

fun Context.toast(@StringRes id: Int){ toast(getString(id)) }
fun Context.toast(@StringRes id: Int,vararg any: Any){ return toast(getString(id,any)) }

//---------------------------------------------------View显示与隐藏-----------------------------------------------------
fun View.gone(){ visibility = View.GONE }
fun View.show(){ visibility = View.VISIBLE }
fun View.invisible(){ visibility = View.INVISIBLE }

//--------------------------------------------------日志打印------------------------------------------------------------
fun Any.i(info: String){ Log.i(this::javaClass.name,info) }
fun Any.d(info: String){ Log.d(this::javaClass.name,info) }
fun Any.v(info: String){ Log.v(this::javaClass.name,info) }
fun Any.w(info: String){ Log.w(this::javaClass.name,info) }
fun Any.e(error: String){ Log.e(this::javaClass.name,error) }
fun Any.i(tag: String,info: String){ Log.i(tag,info) }
fun Any.d(tag: String,info: String){ Log.d(tag,info) }
fun Any.v(tag: String,info: String){ Log.v(tag,info) }
fun Any.w(tag: String,info: String){ Log.w(tag,info) }
fun Any.e(tag: String,error: String){ Log.e(tag,error) }

//--------------------------------------------------视图查询------------------------------------------------------------
fun <V: View> Activity.findView(id: Int): V?{ return findViewById(id)}
fun <V: View> RecyclerView.ViewHolder.findView(id: Int): V?{ return itemView.findViewById(id)}

/**
 * 需要在设置视图之后调用
 */
fun <V: View> Fragment.findView(id: Int): V?{ return view?.findViewById(id) }
fun <V: View> PopupWindow.findView(id: Int): V?{ return contentView?.findViewById(id) }

//---------------------------------------------------获取db尺寸-----------------------------------------------------

fun Context.dp(dp: Int): Int{ return (dp * resources.displayMetrics.density).toInt()}
fun Context.dp(dp: Float): Float{ return dp * resources.displayMetrics.density}
fun Fragment.dp(dp: Int): Int{ return (dp * resources.displayMetrics.density).toInt()}
fun Fragment.dp(dp: Float): Float{ return dp * resources.displayMetrics.density}
fun View.dp(dp: Int): Int{ return (dp * resources.displayMetrics.density).toInt()}
fun View.dp(dp: Float): Float{ return dp * resources.displayMetrics.density}
fun RecyclerView.ViewHolder.dp(dp: Int): Int{ return (dp * itemView.resources.displayMetrics.density).toInt()}
fun RecyclerView.ViewHolder.dp(dp: Float): Float{ return dp * itemView.resources.displayMetrics.density}
fun PopupWindow.dp(dp: Int): Int{ return (dp * contentView.resources.displayMetrics.density).toInt()}
fun PopupWindow.dp(dp: Float): Float{ return dp * contentView.resources.displayMetrics.density}


//---------------------------------------------------获取字符串------------------------------------------------------
fun Fragment.getString(@StringRes id: Int): String{ return context!!.getString(id) }
fun Fragment.getString(@StringRes id: Int,vararg any: Any): String{ return context!!.getString(id,any) }

fun View.getString(@StringRes id: Int):String{ return context.getString(id) }
fun View.getString(@StringRes id: Int,vararg any: Any): String{ return context.getString(id,any) }

fun RecyclerView.ViewHolder.getString(@StringRes id: Int): String{ return itemView.getString(id) }
fun RecyclerView.ViewHolder.getString(@StringRes id: Int,vararg any: Any): String{ return itemView.getString(id,any) }

fun PopupWindow.getString(@StringRes id: Int): String{ return contentView?.getString(id) ?: ""}
fun PopupWindow.getString(@StringRes id: Int,vararg any: Any): String{ return contentView?.getString(id,any) ?: ""}

//----------------------------------------------------软键盘相关-------------------------------------------------------
fun Context.hideKeyboard(view: View){
    view.clearFocus()
    val inputManager = getSystemService(Activity.INPUT_METHOD_SERVICE) as? InputMethodManager
    inputManager?.hideSoftInputFromWindow(view.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
}

fun Context.showKeyboard(view: View){
    view.requestFocus()
    val inputManager = getSystemService(Activity.INPUT_METHOD_SERVICE) as? InputMethodManager
    inputManager?.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT)
}

fun Fragment.hideKeyboard(view: View){ context?.hideKeyboard(view) }
fun View.hideKeyboard(view: View){ context?.hideKeyboard(view) }
fun RecyclerView.ViewHolder.hideKeyboard(view: View){ itemView.hideKeyboard(view) }
fun PopupWindow.hideKeyboard(view: View){ contentView?.hideKeyboard(view) }


fun Fragment.showKeyboard(view: View){ context?.showKeyboard(view) }
fun View.showKeyboard(view: View){ context?.showKeyboard(view) }
fun RecyclerView.ViewHolder.showKeyboard(view: View){ itemView.showKeyboard(view) }
fun PopupWindow.showKeyboard(view: View){ contentView?.showKeyboard(view) }



//----------------------------------------------------进程相关-------------------------------------------------------
fun Context.isAlive(processesName: String = ""): Boolean{
    // 获取指定进程存活状态
    val manager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
    for(processes in manager.runningAppProcesses){
        if(processes.processName == (packageName + processesName)) return true
    }
    return false
}

//----------------------------------------------------打开窗口或服务-------------------------------------------------------

fun <A> Activity.startActivity(clazz: Class<A>,needFinish: Boolean = false){
    startActivity(Intent(this,clazz))
    if(needFinish)finish()
}

fun <A> Fragment.startActivity(clazz: Class<A>,needFinish: Boolean = false){
    activity?.startActivity(Intent(activity,clazz))
    if(needFinish)activity?.finish()
}

fun <A> View.startActivity(clazz: Class<A>){
    context.startActivity(Intent(context,clazz))
}

fun <A> Context.startActivity(clazz: Class<A>){
    startActivity(Intent(this,clazz))
}

fun <A> Activity.startService(clazz: Class<A>){
    startService(Intent(this,clazz))
}

fun <A> Fragment.startService(clazz: Class<A>){
    activity?.startService(Intent(activity,clazz))
}

fun <A> View.startService(clazz: Class<A>){
    context.startService(Intent(context,clazz))
}

fun <A> Context.startService(clazz: Class<A>){
    startService(Intent(this,clazz))
}



//-----------------------------------------------------日期相关--------------------------------------------------------

fun Any.tomorrow(): Long{
    // 获取当前时间到第二天的差值
    val calendar = Calendar.getInstance()
    calendar.add(Calendar.DAY_OF_YEAR,1)
    calendar.set(Calendar.HOUR_OF_DAY,0)
    calendar.set(Calendar.MINUTE,0)
    calendar.set(Calendar.SECOND,0)
    calendar.set(Calendar.MILLISECOND,0)
    return calendar.timeInMillis - System.currentTimeMillis()
}

@SuppressLint("SimpleDateFormat")
fun Any.timeString(time: Long, format: String = "yyyy-MM-dd HH:mm"): String{
    // 时间戳转换字符串
    return SimpleDateFormat(format).format(Date(time))
}

fun Any.timeLong(timeString: String,format: String = "yyyy-MM-dd HH:mm"): Long{
    // 字符串转换时间戳
    return try { SimpleDateFormat(format).parse(timeString).time }catch (e: Exception){0L}
}


//-----------------------------------------------------窗口显示相关--------------------------------------------------------
fun Activity.fullScreen(): Boolean{
    // 窗口全屏模式 SDK版本必须大于等于21 根据返回状态偏移控件位置 避免被遮挡
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
        window.statusBarColor = Color.TRANSPARENT
        window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE)
        return true
    }
    return false
}

fun Activity.fullScreenBlackText(): Boolean{
    // 窗口全屏 深色字体和图标 SDK版本必须大于等于23 根据返回状态偏移控件位置 避免被遮挡
    return if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
        window.statusBarColor = Color.TRANSPARENT
        window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
        true
    }else{
        fullScreen()
    }
}

fun Activity.statusHeight(): Int{
    // 获取状态栏高度
    return try {
        resources.getDimensionPixelOffset(resources.getIdentifier("status_bar_height", "dimen", "android"))
    }catch (e: Exception){
        0
    }
}

//-----------------------------------------------------随机字符串--------------------------------------------------------

fun Any.randomAll(@IntRange(from = 1)length: Int = 10): String{
    // 随机指定长度的字符串 包含 数字 字母
    val string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
    val random = Random()
    val sb = StringBuffer()
    var number: Int
    for (i in 0 until length) {
        number = random.nextInt(string.length)
        sb.append(string[number])
    }
    return sb.toString()
}

fun Any.randomString(@IntRange(from = 1)length: Int = 10): String{
    // 随机指定长度的字符串 字母
    val string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    val random = Random()
    val sb = StringBuffer()
    var number: Int
    for (i in 0 until length) {
        number = random.nextInt(string.length)
        sb.append(string[number])
    }
    return sb.toString()
}

fun Any.randomNumber(@IntRange(from = 1)length: Int = 10): String{
    // 随机指定长度的字符串 数字
    val string = "0123456789"
    val random = Random()
    val sb = StringBuffer()
    var number: Int
    for (i in 0 until length) {
        number = random.nextInt(string.length)
        sb.append(string[number])
    }
    return sb.toString()
}

//-----------------------------------------------------获取点坐标--------------------------------------------------------
fun Any.getCoordinate(angle: Float, radius: Float, centerPoint: PointF, point: PointF = PointF()): PointF{
    //根据角度 圆心 半径 获取点坐标
    point.x = (centerPoint.x + radius * cos(angle * PI /180)).toFloat()
    point.y = (centerPoint.y + radius * sin(angle * PI /180)).toFloat()
    return point
}

//-----------------------------------------------------图片相关--------------------------------------------------------
fun Any.blurBitmap(context: Context,id: Int,@FloatRange(from = 0.0,to = 25.0)radius: Float = 13f):Bitmap{
    // 模糊图片
    return blurBitmap(context,BitmapFactory.decodeResource(context.resources,id),radius)
}

fun Any.blurBitmap(context: Context,bitmap: Bitmap,@FloatRange(from = 0.0,to = 25.0)radius: Float = 13f):Bitmap{
    val script = RenderScript.create(context)
    val input = Allocation.createFromBitmap(script,bitmap)
    val output  = Allocation.createTyped(script,input.type)
    val blur = ScriptIntrinsicBlur.create(script, Element.U8_4(script))
    blur.setInput(input)
    blur.setRadius(radius)
    blur.forEach(output)
    output.copyTo(bitmap)
    script.destroy()
    return bitmap
}

fun Any.getBitmap(drawable: Drawable): Bitmap?{
    // drawable 转 bitmap
    try {
        val bitmap = Bitmap.createBitmap(drawable.intrinsicWidth,drawable.intrinsicHeight,if(drawable.opacity !=PixelFormat.OPAQUE) Bitmap.Config.ARGB_8888 else Bitmap.Config.RGB_565)
        val canvas = Canvas(bitmap)
        drawable.setBounds(0,0,drawable.intrinsicWidth,drawable.intrinsicHeight)
        drawable.draw(canvas)
        return bitmap
    }catch (e: Exception){}
    return null
}

fun Any.compressBitmap(bitmap: Bitmap,@IntRange(from = 0,to = 100)quality: Int = 100): Bitmap{
    // 压缩bitmap  quality指定压缩率
    var outputStream: ByteArrayOutputStream? = null
    var bitmap = bitmap
    try {
        outputStream = ByteArrayOutputStream()
        bitmap.compress(Bitmap.CompressFormat.PNG,quality,outputStream)
        val array = outputStream.toByteArray()
        bitmap = BitmapFactory.decodeByteArray(array, 0, array.size)
    }catch (e: Exception){}
    return bitmap
}

fun Any.getDrawable(context: Context,bitmap: Bitmap) = BitmapDrawable(context.resources,bitmap)

//-----------------------------------------------------获取两点直线距离--------------------------------------------------------
fun Any.getDistance(point1: PointF,point2: PointF) = getDistance(point1.x,point1.y,point2.x,point2.y)
fun Any.getDistance(x1: Float,y1: Float,x2: Float,y2: Float) = sqrt((x1 - x2).toDouble().pow(2.0) + (y1 - y2).toDouble().pow(2.0))

//-----------------------------------------------------颜色值转换--------------------------------------------------------
fun Any.toRGB(color: Int) = intArrayOf((color shr  16) and  0xFF,(color shr  8) and  0xFF,color and  0xFF)

fun Any.toRGB(color: String) = toRGB(Color.parseColor(color))
fun Any.getHTML(color: Int) = String.format("#%06X", 0xFFFFFF and  color)




